_package("mail.ui");

_import("alz.mui.Component");
_import("mail.ui.PaneFrame");
_import("mail.ui.PaneAppContent");

/**
 * N个Pane组件层叠管理组件（Pane组件停放甲板）
 * 实际上是一个 Pane 组件管理者(PaneManager)，只不过也划归UI组件类了
 */
_class("DeckPane", Component, function(){
	this._init = function(){
		_super._init.call(this);
		this._app = null;
		/* *
		 * PaneFrame和PaneAppContent实例的集合
		 * default  mailinfo页面使用(默认)
		 * external 百宝箱等跨域的页面使用
		 */
		this._panes = {};
		this._activePane = null;
	};
	this.bind = function(obj, app){
		this._app = app;
		_super.bind.apply(this, arguments);
		//this.init(obj);
	};
	this.init = function(obj){
		_super.init.apply(this);
	};
	this.dispose = function(){
		this._activePane = null;
		for(var k in this._panes){
			this._panes[k].dispose();
			delete this._panes[k];
		}
		this._app = null;
		_super.dispose.apply(this);
	};
	this.createPane = function(key, appConf, opoa){
		var clazz = opoa ? PaneAppContent : PaneFrame;
		var pane = new clazz();
		pane.setId(key);
		pane.create(this._self, this._app, key == "default");  //参数3表示是否默认的Pane组件(会影响iframe是否带滚动条)
		if(key == "default"){  //默认的Pane组件
			pane.setIframeName("mainbody");
		}
		this._app._navTabbar.appendTab(appConf ? appConf.title : key, appConf, pane);
		this._panes[key] = pane;
		return pane;
	};
	/**
	 * 根据参数appid创建一个对应的PaneAppContent组件
	 * @param appid {String} App的id标识(目前和当前的action一致)
	 */
	this.createAppPane = function(key, agent, func){
		var appid = key.split("_").pop();
		var appConf = runtime.getAppManager().getAppConf(appid);
		var pane = this.createPane(key, appConf, true);  //参数3表示是否单页面用的Pane组件
		appConf = null;
		return pane;
	};
	/**
	 * 显示一个单页面应用面板
	 */
	this.getAppPane = function(key, appConf, params, offset, updateHistory){
		var pane = key in this._panes ? this._panes[key] : this.createAppPane(key);
		/*
		需要先显示出来通讯录页面，然后对里面的组件执行显示隐藏操作，不然将会
		出现下面的BUG，父容器没有显示之前，内部子容器的显示隐藏操作无效！
		RQFM-5620 cn邮箱中，"从其他邮箱导入联系人"页面显示有误
		*/
		var ret = this.setActivePane(pane);
		if(ret){
			if(updateHistory){
				if(params.action != "invite_mail"){
					var hm = this._app.historyManager;
					var params0 = hm.getLength() > 0 ? hm.item(hm.getLength() - 1) : null;
					//action和act参数都一致时，不更新历史纪录，主要是为了解决这类历史记录问题：
					//RQFM-6015 COM邮箱，进入写信息页面后，点击多次"写信"按钮，此时点击"取消"按钮，无效
					if(params0 && params0.action == params.action && params0.act == params.act){
					}else{
						hm.putHistory(params, offset);  //先于navigate执行很重要
					}
					params0 = null;
					hm = null;
				}
			}
			if(!pane._contentPane){  //还没有初始化的话
				this.loadAppFiles(pane, appConf, this, function(){
					var conf = this._app.getAppConf(appConf.id);
					//if(conf[0] == 0 && ret){  //前提必须是非单页面机制
					var useCache = conf[2] == 1;  //使用页面缓存的模块
					//if(conf[3] == 0){  //如果是外域APP
					//	params.url = "http://app.mail.sina.com.cn/sinamail-dev" + params.url;
					//}
					pane.navigate(this._app.formatUrl(params.url, true), useCache, params);
					pane = null;
					//}
				});
			}else if(params){  //新创建的在回调完成后执行navigate动作
				//这里只是调用AppXXX::renini方法，恢复App的初始状态
				pane.navigate(this._app.formatUrl(params.url, true), true, params);
				pane = null;
			}
		}
		return ret;
	};
	this.loadAppFiles = function(pane, appConf, agent, func){
		var cbid = runtime._task.add(agent, func);
		var className = appConf.className;
		pane._self.setAttribute("_class", className);  //为了验证之用
		//pane.navigate(this._app.formatUrl(obj.url, true));

		//加载css文件
		appConf["skinid"] = runtime.getConfData("skinid");
		appConf["css"] = appConf["css"].replace(/\{\$(\w+)\}/g, function(_0, _1){
			if(_1 in appConf){
				if(_1 == "skinid"){
					var no = "" + (parseInt(appConf[_1]) + 1);
					//return "000".substr(0, 3 - no.length) + no;
					return no;
				}else{
					return appConf[_1];
				}
			}else{
				return _0;
			}
		});
		runtime.dynamicLoadFile("css", this._app._pathCss, appConf["css"].split(","), this._app._pathSkin);

		//加载APP依赖文件(tpl,lib)
		var libName = appConf.libName;
		var ret = this._app.getAppManager().loadAppFiles(libName, this._app, this._app, function(app){
			//pane._contentApp = app;
			app.init(pane);
			//app.onContentLoad(libName);
			runtime.eventHandle({type: "resize"});  //主动触发一次 resize 事件
			//[TODO]回调中只是一个reset动作，已经在app的init方法中执行了
			/*
			if(func){
				runtime._task.execute(cbid);
			}
			*/
		});
		if(!ret && func){
			runtime._task.execute(cbid);
		}
	};
	/**
	 * 显示一个iframe应用面板(外域使用唯一的key="external")
	 */
	this.getFramePane = function(key, appConf, params, n, updateHistory){  //key = "tpl_" + appid
		//if(appid == "maillist"){  //为每个邮件夹分别创建一个PaneFrame类
		//	key += "_" + params.fid;
		//}
		var pane = key in this._panes ? this._panes[key] : this.createPane(key, appConf, false);
		var ret = this.setActivePane(pane);
		if(ret && params){
			var useCache = appConf ? appConf.conf[2] == 1 : false;  //使用页面缓存的模块
			pane.navigate(this._app.formatUrl(params.url), useCache, params);
		}
		if(updateHistory && ret){
			this._app.historyManager.putHistory(params, n);
		}
		pane = null;
		return ret;
	};
	/**
	 * APP功能模块导航，单页面环境下模拟子页面的导航机制
	 * @param params {url:"",title:"",action:"",...}
	 * @param offset {Number} 历史纪录偏移量，默认0
	 * @param updateHistory {Boolean} 是否更新历史纪录
	 */
	this.navigate = function(params, offset, updateHistory){
		if(!("url" in params)){
			runtime.error("[DeckPane::navigate]参数params缺少url属性，不知如何导航");
			return false;
		}
		if(typeof offset == "undefined") offset = 0;
		if(typeof updateHistory != "boolean") updateHistory = true;
		var ret;
		var appid = params.action;  //appid和action一致！
		//if("title" in params) this._app.showTipInfo("正在打开" + title + "……");
		if(appid == "maillist" && this._app._viewMode == 0){
			this._app._setViewMode(1);
		}
		var host = params.url.replace(/http:\/\/([^\/]+)\/.*/, "$1");
		if(params.url.indexOf("http://") == 0 && host != window.location.host){  //检查是否跨域访问，防止跨域报错
			ret = this.getFramePane("external", null, params, offset, updateHistory);
		}else{
			var appConf = runtime.getAppManager().getAppConf(appid);
			var conf = this._app.getAppConf(appid);
			if(conf[0] == 1){  //使用单页面机制工作
				ret = this.getAppPane("tpl_" + appid, appConf, params, offset, updateHistory);
			}else if(conf[1] == 1){  //不同的模板是否使用不同的PaneFrame组件？
				ret = this.getFramePane("tpl_" + appid, appConf, params, offset, updateHistory);
			}else{
				ret = this.getFramePane("default", appConf, params, offset, updateHistory);  //使用默认的Pane组件工作
			}
			conf = null;
			appConf = null;
		}
		return ret;
	},
	//getPane: function(key){
	//	return this._panes[key];
	//};
	this.getActivePane = function(){
		return this._activePane;
	};
	this.switchPane = function(pane){
		if(this._activePane == pane) return;  //为了防止同一个action中第二次进入setActivePane
		return this.setActivePane(pane);
	};
	this.setActivePane = function(pane){
		//[TODO]需要优化，已经切换过，则直接忽略，但是在每个APP能够区分自己的多种界
		//面状态之前，这个优化动作最好先不打开，不然，再次切换到某个APP中时将不能正
		//确进行的切换。
		//if(this._activePane == pane) return;
		var contentApp;
		if(this._activePane){
			contentApp = this._activePane.getApp();
		}
		if(this._activePane == pane){
			if(contentApp && typeof contentApp.onbeforeunload == "function"){
				var str;
				try{
					str = contentApp.onbeforeunload();
				}catch(ex){  //防止错误“不能执行已经释放的Script代码”产生
					str = null;
				}
				if(str && !window.confirm(str)){
					return false;  //不影响历史记录
				}
			}
			return true;
		}
		if(this._activePane && contentApp){
			//如果之前显示页面的app有设置onbeforeunload的话，说明有未保存的信息要提示，
			//这里主动调用一次onbeforeunload，工作机制模仿window.onbeforeunload的工作
			//方式，onbeforeunload返回非空字符串的话，则执行confirm提示
			var str;
			if(typeof contentApp.onbeforeunload == "function"){
				try{
					str = contentApp.onbeforeunload();
				}catch(ex){  //防止错误“不能执行已经释放的Script代码”产生
					str = null;
				}
				if(str && !window.confirm(str)){
					return false;  //不影响历史记录
				}
			}
			if(typeof contentApp.onunload == "function"){
				try{
					contentApp.onunload();
				}catch(ex){  //防止错误“不能执行已经释放的Script代码”产生
				}
			}
			//this._activePane.setVisible(false);
			//pane.moveTo(parseInt(this._activePane._self.style.left), parseInt(this._activePane._self.style.top));
		}
		pane.setVisible(true);
		if(this._activePane){
			pane._self.style.position = "absolute";
			var x = runtime.dom.getStyleProperty(this._activePane._self, "left");
			var y = runtime.dom.getStyleProperty(this._activePane._self, "top");
			var w = runtime.dom.getStyleProperty(this._activePane._self, "width");
			var h = runtime.dom.getStyleProperty(this._activePane._self, "height");
			runtime.dom.moveElement(pane._self, x, y);  //pane.moveTo(x, y);
			runtime.dom.resizeElement(pane._self, w, h);  //pane.resize(w, h);
			/*if(this._activePane._self.parentNode.__layout){
				this._activePane._self.parentNode.__layout.setClientNode(pane._self);
			}*/
			this._activePane.setVisible(false);
		}
		try{
			pane._self.focus();
		}catch(ex){
		}
		this._activePane = pane;
		this._app._navTabbar.activeTab(pane.getTab());
		//this._app.resize();  //该句影响pane的display属性，导致IFRAME遮挡超链接，链接失效
		return true;  //影响历史记录
	};
	this.onResize = function(){
		if(this._activePane){
			var cw = Math.max(0, this._self.offsetWidth
				//- runtime.dom.getStyleProperty(this._self, "borderLeftWidth")
				- runtime.dom.getStyleProperty(this._self, "paddingLeft")
				- runtime.dom.getStyleProperty(this._self, "paddingRight")
				//- runtime.dom.getStyleProperty(this._self, "borderRightWidth")
			);
			var ch = Math.max(0, this._self.offsetHeight
				//- runtime.dom.getStyleProperty(this._self, "borderTopWidth")
				- runtime.dom.getStyleProperty(this._self, "paddingTop")
				- runtime.dom.getStyleProperty(this._self, "paddingBottom")
				//- runtime.dom.getStyleProperty(this._self, "borderBottomWidth")
			);
			this._activePane.resize(cw, ch);
		}
		/*
		for(var k in this._panes){
			var pane = this._panes[k];
			if(pane.getVisible()){
				//pane._self.style.left = (w_sider + mm[1]) + "px";
				pane.resize(Math.max(0, pane._self.clientWidth), pane._self.clientHeight);
			}
			pane = null;
		}
		*/
	};
	this.onSkinChange = function(skinId){
		for(var k in this._panes){
			var pane = this._panes[k];
			var app = pane._app;
			if(app){
				if(app._doc != this._app._doc){  //单页面应用下是相同的
					this._app.chgSkinCss(app._doc, this._app._skinId);
				}
			}else if(pane._iframe){
				try{
					this._app.chgSkinCss(pane._iframe.contentWindow.document, this._app._skinId);
				}catch(ex){  //屏蔽跨域错误
				}
			}
			pane = null;
		}
	};
});